/*
 *   JVending
 *   Copyright (C) 2004  Shane Isbell
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package org.jvending.provisioning.impl;

import org.jvending.provisioning.config.*;
import org.jvending.provisioning.dao.BundleDescriptorDAO;
import org.jvending.provisioning.dao.ClientBundleDAO;
import org.jvending.provisioning.dao.DeliveryEventDAO;
import org.jvending.provisioning.dao.FulfillmentTaskDAO;
import org.jvending.provisioning.model.fulfillmenttask.FulfillmentTaskObject;
import org.jvending.provisioning.stocking.DataSink;
import org.jvending.provisioning.stocking.StockingContext;
import org.jvending.provisioning.stocking.StockingException;
import org.jvending.provisioning.stocking.handler.StockingHandlerConfig;
import org.jvending.registry.RepositoryRegistry;
import org.jvending.registry.ServletRepositoryLoader;
import org.jvending.registry.hibernate.HibernateDAORegistry;

import javax.provisioning.*;
import javax.provisioning.adapter.*;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Provides an implementation of the <code>ProvisioningContext</code> and the <code>AdapterContext</code>.
 *
 * @author Shane Isbell
 * @since 1.3a
 */

//TODO: Optimize
public final class ProvisioningContextImpl implements ProvisioningContext, AdapterContext, ServletContextListener {

    private static Logger logger = Logger.getLogger("ProvisioningContextImpl");//Last log: 44

    private ServletContext servletContext;

    protected DeviceRepository deviceRepository;

    protected AdapterRepositoryWrapper adapterRepositoryWrapper;

    protected RepositoryRegistry repositoryRegistry;

    protected HibernateDAORegistry hibernateDaoRegistry;

    protected DeliveryComponent deliveryComponent;

    private StockingContext stockingContext;

    private JVendingRepository jvendingRepository;

    /**
     * Constructor for the servlet container
     */
    public ProvisioningContextImpl() {
    }

    /**
     * Constructor for unit tests
     *
     * @param deviceRepository
     * @param adapterRepositoryWrapper
     * @param repositoryRegistry
     * @param hibernateDaoRegistry
     * @param jvendingRepository
     */
    public ProvisioningContextImpl(DeviceRepository deviceRepository,
                                   AdapterRepositoryWrapper adapterRepositoryWrapper,
                                   RepositoryRegistry repositoryRegistry,
                                   HibernateDAORegistry hibernateDaoRegistry,
                                   JVendingRepository jvendingRepository) {
        this.deviceRepository = deviceRepository;
        this.adapterRepositoryWrapper = adapterRepositoryWrapper;
        this.repositoryRegistry = repositoryRegistry;
        this.hibernateDaoRegistry = hibernateDaoRegistry;
        this.jvendingRepository = jvendingRepository;
    }

    public void contextInitialized(ServletContextEvent servletContextEvent) {
        logger.info("JV-1500-037: Starting the Provisioning Server Context");
        servletContext = servletContextEvent.getServletContext();
        String provisioningConfig = servletContext.getInitParameter("PROVISIONING_CONFIG");
        if (provisioningConfig == null) {
            logger.severe("JV-1500-001: Could not find the PROVISIONING_CONFIG init parameter from the servlet context: Value = "
                    + provisioningConfig);
            return;
        }
        try {
            InputStream inputStream = servletContext.getResourceAsStream(provisioningConfig);
            if (inputStream == null) {
                logger.severe("JV-1500-002: Could not find PROVISIONING_CONFIG from resource: Value = "
                        + provisioningConfig);
                return;
            }
            logger.info("JV-1500-003: Loaded PROVISIONING_CONFIG = " + provisioningConfig);
            repositoryRegistry = RepositoryRegistry.Factory.create();
            hibernateDaoRegistry = HibernateDAORegistry.Factory.create();
            repositoryRegistry.setRepositoryLoader(new ServletRepositoryLoader(servletContext));
            repositoryRegistry.loadFromInputStream(inputStream);
            hibernateDaoRegistry.setRepositoryRegistry(repositoryRegistry);
        } catch (IOException e) {
            e.printStackTrace();
            logger.info("JV-1500-004: Failed to load registries");
            return;
        }

        deviceRepository = (DeviceRepository) repositoryRegistry.find("devices");
        AdapterRepository adapterRepository = (AdapterRepository) repositoryRegistry.find("adapters");
        jvendingRepository = (JVendingRepository) repositoryRegistry.find("jvending");
        if (deviceRepository == null) {
            logger.severe("JV-1500-005: Device repository is null within provisioning context!");
        }

        if (adapterRepository == null) {
            logger.severe("JV-1500-006: Adapter repository is null within provisioning context!");
        }

        adapterRepositoryWrapper = new AdapterRepositoryWrapper(adapterRepository, this);
        DeliveryEventDAO deliveryEventDAO = (DeliveryEventDAO) hibernateDaoRegistry.find("dao:delivery-event");

        try {
            deliveryComponent = new DeliveryComponentImpl(deliveryEventDAO);
            deliveryComponent.init(this);
        } catch (ServletException e) {
            e.printStackTrace();
            logger.severe("JV-1500-43: Could not initialize the DeliveryComponent");
            throw new Error("JV-1500-43: Could not initialize the DeliveryComponent");
        }

        servletContext.setAttribute("javax.provisioning.ProvisioningContext", this);
        servletContext.setAttribute("org.jvending.registry.RepositoryRegistry", repositoryRegistry);
        servletContext.setAttribute("org.jvending.registry.hibernate.HibernateDAORegistry", hibernateDaoRegistry);

        stockingContext = new StockingContextImpl();
        stockingContext.init(servletContext);
        //TODO: Federation context
        logger.info("JV-1500-038: Sucessfully started the Provisioning Server Context");
    }


    public void contextDestroyed(ServletContextEvent event) {
        logger.info("JV-1500-039: Destroying the Provisioning Server Context");

        //Destroy the Adapters:
        List adapterInfos = getAdapterInfos();
        for (Iterator i = adapterInfos.iterator(); i.hasNext();) {
            AdapterInfo adapterInfo = (AdapterInfo) i.next();
            String adapterName = adapterInfo.getAdapterName();
            Adapter adapter = getAdapter(adapterName);
            if (adapter != null) {
                try {
                    adapter.destroy();
                    logger.info("JV-1500-41: Destroyed adapter: Name = " + adapterName);
                } catch (AdapterException e) {
                    e.printStackTrace();
                    logger.info("JV-1500-40: Unable to cleanup resources from an adapter: Name = " + adapterName);
                }
            }
        }

        deliveryComponent.destroy();
        logger.info("JV-1500-42: Destroyed delivery component");

        servletContext.removeAttribute("javax.provisioning.ProvisioningContext");
        servletContext.removeAttribute("org.jvending.registry.RepositoryRegistry");
        servletContext.removeAttribute("org.jvending.registry.hibernate.HibernateDAORegistry");

        stockingContext.destroy();
    }

    public FulfillmentTask createFulfillmentTask(BundleDescriptor bundleDescriptor,
                                                 DeliveryContext deliveryContext) throws ProvisioningException {
        if (bundleDescriptor == null) throw new ProvisioningException("JV-1500-007: Bundle Descriptor is null.");

        return createFulfillmentTask(bundleDescriptor,
                deliveryContext,
                getDefaultAdapterName(bundleDescriptor, deliveryContext));
    }

    public FulfillmentTask createFulfillmentTask(BundleDescriptor bundleDescriptor,
                                                 DeliveryContext deliveryContext, String adapterName)
            throws ProvisioningException {
        if (bundleDescriptor == null)
            throw new ProvisioningException("JV-1500-008: Bundle Descriptor is null: AdapterName = " + adapterName);

        if (adapterName == null) adapterName = getDefaultAdapterName(bundleDescriptor, deliveryContext);
        return createFulfillmentTask(bundleDescriptor, deliveryContext, adapterName, 0);

    }

    public FulfillmentTask createFulfillmentTask(BundleDescriptor bundleDescriptor,
                                                 DeliveryContext deliveryContext, String adapterName, long duration)
            throws ProvisioningException {
        if (bundleDescriptor == null)
            throw new ProvisioningException("JV-1500-009: Bundle Descriptor is null. AdapterName = "
                    + adapterName + ", Duration = " + duration);

        if (adapterName == null) adapterName = getDefaultAdapterName(bundleDescriptor, deliveryContext);
        if (adapterRepositoryWrapper.getAdapterFor(adapterName) == null) {
            logger.warning("JV-1500-010: Could not find adapter: Name = " + adapterName);
            throw new ProvisioningException("JV-1500-010: Could not find adapter: Name = " + adapterName);
        }

        FulfillmentTask task =
                ProvisioningFactory.createFulfillmentTask(bundleDescriptor, deliveryContext, adapterName, duration, this);

        try {
            FulfillmentTaskObject taskObject =
                    new FulfillmentTaskObject();
            taskObject.setFulfillmentID(task.getFulfillmentID());
            taskObject.setExpiryTime(task.getExpiryTime());
            taskObject.setBundleDescriptorId(task.getBundleDescriptor().getBundleID());
            FulfillmentTaskDAO fulfillmentTaskDAO =
                    (FulfillmentTaskDAO) hibernateDaoRegistry.find("dao:fulfillment-task");
            if (fulfillmentTaskDAO == null)
                throw new ProvisioningException("JV-1500-011: Could not find DAO: DAO = dao:fulfillment-task"
                        + ", AdapterName = " + adapterName);

            fulfillmentTaskDAO.store(taskObject);
        } catch (IOException e) {
            logger.log(Level.INFO, "JV-1500-011: Could not create fulfillment task: AdapterName = " + adapterName, e);
            throw new ProvisioningException("JV-1500-012: Could not create fulfillment task: AdapterName = "
                    + adapterName);
        }

        return task;
    }

    //TODO: Does returning unmodifiable list violate spec? Spec - Make sure that the order returned is the same as in
    //the config file
    public List getAdapterInfos() {
        List adapterInfos = adapterRepositoryWrapper.getAdapterInfos();
        return (adapterInfos != null) ? adapterInfos : Collections.unmodifiableList(new ArrayList());
    }

    public List getAdapterInfos(BundleDescriptor bundleDescriptor, String deviceId) {
        List adapterNames = null;
        if (bundleDescriptor == null && deviceId == null)
            return adapterRepositoryWrapper.getAdapterInfos();//All AdapterInfos

        if (deviceId != null)
            adapterNames = deviceRepository.getAdapterNamesFor(deviceId);//AdapterNames filtered by device
        else if (bundleDescriptor != null)
            adapterNames = adapterRepositoryWrapper.getAdapterNames();//All AdapterNames

        List adapterInfos = new ArrayList();

        logger.finest("JV-1500-013: Found Adapters: Count = " + adapterNames.size() + ", Device Id = " + deviceId);

        for (Iterator i = adapterNames.iterator(); i.hasNext();) {
            String adapterName = ((String) i.next()).trim();
            AdapterInfo adapterInfo = adapterRepositoryWrapper.getAdapterInfoFor(adapterName);

            if (bundleDescriptor != null &&
                    bundleDescriptor.getDescriptorFile() != null &&
                    matchDescriptorFile(adapterInfo, bundleDescriptor)) {

                logger.finest("JV-1500-014: Added adapter for descriptor to list: Name = " + adapterName);
                adapterInfos.add(adapterInfo);
            } else if (bundleDescriptor != null &&
                    bundleDescriptor.getContentFile() != null &&
                    adapterInfo.getDescriptorFileExtension() == null &&
                    adapterInfo.getDescriptorFileMimeType() == null) {

                logger.finest("JV-1500-015: Added adapter for content to list: Name = " + adapterName);
                adapterInfos.add(adapterInfo);
            } else if (bundleDescriptor == null) {
                logger.finest("JV-1500-016: Added adapter to list: Name = " + adapterName);
                adapterInfos.add(adapterInfo);
            }
        }
        return adapterInfos;
    }

    public BundleRepository getBundleRepository() {
        ClientBundleDAO clientBundleDAO = (ClientBundleDAO) hibernateDaoRegistry.find("dao:client-bundle");
        BundleDescriptorDAO bundleDescriptorDAO =
                (BundleDescriptorDAO) hibernateDaoRegistry.find("dao:bundle-descriptor");
        AttributeMatcherRepository matcherRepository = (AttributeMatcherRepository) repositoryRegistry.find("matchers");
        MimeTypeRepository mimeTypeRepository = (MimeTypeRepository) repositoryRegistry.find("mimetype");
        DeliverableRepository deliverableRepository = (DeliverableRepository) repositoryRegistry.find("deliverables");
        DataSink dataSink = new BundleRepositoryImpl(clientBundleDAO, bundleDescriptorDAO,
                null, matcherRepository, mimeTypeRepository, deliverableRepository, this);

        StockingHandlerConfig config = null;
        try {
            config = stockingContext.getStockingHandler("GENERIC").getStockingHandlerConfig();
        } catch (StockingException e) {
            e.printStackTrace();
        }
        dataSink.init(config);
        return (BundleRepository) dataSink;

    }

    public DeliveryContext getDeliveryContext(HttpServletRequest request) {//Spec does not define passing in null request
        if(request == null)
        {
            throw new IllegalArgumentException("request");
        }
        return getDeliveryContext(toMap(request));
    }

    private DeliveryContext getDeliveryContext(Map requestMap) {
        if (requestMap == null) {
            logger.info("JV-1500-017: Could not get HTTP parameters from this device. Failing...");
            return null;
        }
        String networkHeader = jvendingRepository.getValue("network-header");
        String userHeader = jvendingRepository.getValue("user-header");
        String networkId = networkHeader != null ? (String) requestMap.get(networkHeader) : null;
        String user = userHeader != null ? (String) requestMap.get(userHeader) : null;

        //TODO: Device repository does not follow spec
        Capabilities capabilities = deviceRepository.getCapabilities(requestMap);
        if (capabilities == null) {
            logger.info("JV-1500-018: Could not get capabilities for this device. Failing...");
            logger.info(requestMap.toString());
            return null;
        }

        return ProvisioningFactory.createDeliveryContext(capabilities, networkId, user, requestMap);
    }

    public Capabilities getDeviceTypeCapabilities(String identifier) {
        return (identifier == null) ? null : deviceRepository.getCapabilitiesFor(identifier.trim());
    }

    public Set getDeviceTypeIdentifiers() {
        return deviceRepository.getDeviceIds();
    }

    public ServletContext getServletContext() {
        return servletContext;
    }

    public String encodeURL(HttpServletRequest request, HttpServletResponse response, String url) {
        return response.encodeURL(url);
    }

    //TODO: Must only be one instance and the init and destroy methods must be called.
    // returns null for invalid adapter Name
    public Adapter getAdapter(String adapterName) {
        return adapterRepositoryWrapper.getAdapterFor(adapterName);
    }

    public AdapterConfig getAdapterConfig(String adapterName) {
        return adapterRepositoryWrapper.getAdapterConfigFor(adapterName);
    }

    public DeliveryComponent getDeliveryComponent() {
        return deliveryComponent;
    }

    public FulfillmentTask getFulfillmentTask(String fulfillmentID,
                                              DeliveryContext deliveryContext,
                                              String adapterName)
            throws AdapterException, InvalidFulfillmentIDException {
        FulfillmentTaskDAO fulfillmentTaskDAO = (FulfillmentTaskDAO) hibernateDaoRegistry.find("dao:fulfillment-task");
        if (fulfillmentTaskDAO == null)
            throw new AdapterException(adapterName, "JV-1500-019: Could not find DAO: DAO = dao:fulfillment-task, AdapterName ="
                    + adapterName);
        if (fulfillmentID == null) throw new InvalidFulfillmentIDException(adapterName,
                "Cannot get a FulfillmentTask with a null id", null, "null");

        FulfillmentTask fulfillmentTask = (FulfillmentTask) getServletContext().getAttribute(fulfillmentID);

        if (fulfillmentTask == null) {
            FulfillmentTaskObject fulfillmentTaskObject;
            try {
                fulfillmentTaskObject =
                        fulfillmentTaskDAO.getFulfillmentTaskFor(fulfillmentID);
            } catch (IOException e) {
                throw new InvalidFulfillmentIDException(adapterName, "JV-1500-020: Unable to find task: FulfillmentID = "
                        + fulfillmentID + ", " + e.getMessage(), null, fulfillmentID);
            }
            BundleDescriptor descriptor =
                    getBundleRepository().getBundleByID(fulfillmentTaskObject.getBundleDescriptorId());

            try {
                fulfillmentTask = createFulfillmentTask(descriptor,
                        deliveryContext,
                        adapterName,
                        fulfillmentTaskObject.getExpiryTime());
            } catch (ProvisioningException e) {
                logger.log(Level.INFO, "JV-1500-021: Could not create fulfillment task:" +
                        " Adapter Name = " + adapterName +
                        ", Fulfillment Id = " + fulfillmentID +
                        ", Bundle Descriptor = " + descriptor);
                throw new AdapterException(adapterName, "JV-1500-021: Could not create task. Fulfillment ID = "
                        + fulfillmentID, e);
            }
        }

        if (fulfillmentTask.isExpired())
            throw new InvalidFulfillmentIDException(adapterName, "JV-1500-022: Expired task.", null, fulfillmentID);

        return fulfillmentTask;
    }

    /*
    public FulfillmentTask getFulfillmentTaskWithDeviceId(String fulfillmentID,
                                                          DeliveryContext deliveryContext,
                                                          String deviceId)
            throws AdapterException, InvalidFulfillmentIDException {
        FulfillmentTaskDAO fulfillmentTaskDAO = (FulfillmentTaskDAO) hibernateDaoRegistry.find("dao:fulfillment-task");
        if(fulfillmentTaskDAO == null)
            throw new AdapterException("unknown", "JV-1500-023: Could not find DAO: DAO = dao:fulfillment-task, DeviceId ="
                + deviceId);

        FulfillmentTask fulfillmentTask = (FulfillmentTask) getServletContext().getAttribute(fulfillmentID);
        if (fulfillmentTask != null) {
            if (fulfillmentTask.isExpired())
                throw new InvalidFulfillmentIDException(null, "JV-1500-024: Expired task", null, fulfillmentID);
            return fulfillmentTask;
        }

        FulfillmentTaskObject fulfillmentTaskObject =
                fulfillmentTaskDAO.getFulfillmentTaskFor(fulfillmentID);
        if (fulfillmentTaskObject == null)
            throw new InvalidFulfillmentIDException(null, "JV-1500-025: Unable to find task", null, fulfillmentID);

        BundleDescriptor descriptor =
                getBundleRepository().getBundleByID(fulfillmentTaskObject.getBundleDescriptorId());

        if (descriptor == null) {
            logger.info("JV-1500-026: Could not find bundle descriptor: ID = "
                    + fulfillmentTaskObject.getBundleDescriptorId());
            return null;//?????
        }

        List adapterInfos = getAdapterInfos(descriptor, deviceId);
        if (adapterInfos.size() == 0) {
            logger.info("JV-1500-027: Could not find adapter info: Device Id = " + deviceId);
            throw new AdapterException(null, "JV-1500-027: Could not find adapter info: Fulfillment ID = "
                    + fulfillmentID, null);
        }

        String adapterName = ((AdapterInfo) adapterInfos.get(0)).getAdapterName();

        try {
            fulfillmentTask = createFulfillmentTask(descriptor,
                    deliveryContext,
                    adapterName,
                    fulfillmentTaskObject.getExpiryTime());
        } catch (ProvisioningException e) {
            logger.log(Level.INFO, "JV-1500-028: Could not create fulfillment task:" +
                    " Adapter Name = " + adapterName +
                    ", Fulfillment Id = " + fulfillmentID +
                    ", Bundle Descriptor = " + descriptor);
            throw new AdapterException(adapterName, "JV-1500-028: Could not create task: Fulfillment ID = "
                    + fulfillmentID, e);
        }

        if (fulfillmentTask != null) {
            if (fulfillmentTask.isExpired())
                throw new InvalidFulfillmentIDException(null, "JV-1500-029: Expired task", null, fulfillmentID);
            return fulfillmentTask;
        }
        throw new InvalidFulfillmentIDException(null, "JV-1500-030: Invalid ID", null, fulfillmentID);
    }
*/
    private Map toMap(HttpServletRequest request) {
        Map paramMap = new HashMap();
        if (request == null) return paramMap;
        for (Enumeration en = request.getHeaderNames(); en.hasMoreElements();) {
            String headerName = (String) en.nextElement();
            String headerValue = request.getHeader(headerName);
            paramMap.put(headerName, headerValue);
        }
        return paramMap;
    }

    /**
     *
     *
     */
    private String getDefaultAdapterName(BundleDescriptor descriptor, DeliveryContext context)
            throws ProvisioningException {
        if (descriptor == null) {
            logger.info("JV-1500-031: Bundle Descriptor is null. Cannot obtain adapter name. Try Generic Adapter.");
            return "generic";
        }
        HashSet adapterInfoSet = new HashSet();

        if (context != null) {
            Capabilities capabilities = context.getDeviceCapabilities();
            List capability = capabilities.getCapability(Constants.HardwarePlatform_DeviceIdentifier);

            if (capability == null) {
                List adapterInfos = getAdapterInfos(descriptor, null);
                for (Iterator i = adapterInfos.iterator(); i.hasNext();)
                    adapterInfoSet.add(i.next());
            } else {
                for (Iterator i = capability.iterator(); i.hasNext();) {
                    String deviceId = (String) i.next();
                    List adapterInfos = getAdapterInfos(descriptor, deviceId);
                    for (Iterator j = adapterInfos.iterator(); j.hasNext();)
                        adapterInfoSet.add(j.next());
                }
            }
        } else {
            List adapterInfos = getAdapterInfos(descriptor, null);
            for (Iterator i = adapterInfos.iterator(); i.hasNext();)
                adapterInfoSet.add(i.next());
        }

        Deliverable descriptorFile = descriptor.getDescriptorFile();
        Deliverable contentFile = descriptor.getContentFile();

        //sanity check
        if (descriptorFile != null && contentFile != null) {
            logger.warning("JV-1500-032: Illegal state. Bundle Descriptor has both a descriptor file and content file: Descriptor = " +
                    descriptor);
            throw new ProvisioningException("JV-1500-032: Bundle descriptor contains an illegal state.");
        }

        if (descriptorFile == null && contentFile == null) {
            logger.warning("JV-1500-033: Illegal state. Bundle Descriptor has neither a descriptor file nor a content file: Descriptor = " +
                    descriptor);
            throw new ProvisioningException("JV-1500-033: Bundle descriptor contains an illegal state.");
        }

        if (descriptorFile != null) {//note: the BundleDescriptor already converts file-extension to mime-type
            String mimeType = descriptorFile.getMimeType();
            for (Iterator j = adapterInfoSet.iterator(); j.hasNext();) {
                AdapterInfo adapterInfo = (AdapterInfo) j.next();
                String mimeType2 = adapterInfo.getDescriptorFileMimeType();
                if (mimeType.equals(mimeType2)) {
                    return adapterInfo.getAdapterName();
                }
            }
        } else if (contentFile != null) {
            logger.finest("GENERIC ADAPTER");
            return "generic";
        }
        throw new ProvisioningException("JV-1500-034: Adapter not found.");

    }

    private boolean matchDescriptorFile(AdapterInfo adapterInfo, BundleDescriptor bundleDescriptor) {
        if (bundleDescriptor == null || adapterInfo == null) {
            logger.finest("JV-1500-035: Unable to match adapter info. Either bundle descriptor or adapter info is null.");
            return false;
        }

        BundleDescriptorImpl bundleDescriptorImpl = (BundleDescriptorImpl) bundleDescriptor;

        String adapterFileExtension = adapterInfo.getDescriptorFileExtension();
        String adapterMimeType = adapterInfo.getDescriptorFileMimeType();

        if (adapterMimeType == null && adapterFileExtension == null) {
            logger.finest("JV-1500-036: Unable to match adapter info. Adapter mime-type and file extension are null.");
            return false;
        }

        String bundleFileName = bundleDescriptorImpl.getDescriptorFileName();
        String bundleMimeType = bundleDescriptorImpl.getDescriptorMimeType();

        logger.finest(bundleMimeType + ":" + adapterMimeType + ":" + bundleFileName + ":" + adapterFileExtension);
        return ((bundleMimeType != null && bundleMimeType.equals(adapterMimeType)) ||
                (bundleFileName != null && bundleFileName.endsWith(adapterFileExtension)));
    }
}